package com.campus_assistant.controller.file;


import com.campus_assistant.common.ToVue;
import com.campus_assistant.config.db.DynamicDataSource;
import com.campus_assistant.pojo.db1.Scores;
import com.campus_assistant.service.db1.CoursesService;
import com.campus_assistant.service.db1.ScoresService;
import com.campus_assistant.service.db1.StudentService;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

@CrossOrigin(origins = "http://127.0.0.1:5173",allowCredentials = "true")
@Controller
public class FileUploadController {
    @Autowired
    private StudentService studentService;
    @Autowired
    private CoursesService coursesService;
    @Autowired
    private ScoresService scoresService;
    private final static String encode="utf-8";

    @ResponseBody
    @RequestMapping("/uploadFile")
    public ToVue uploadFile(HttpServletRequest request, HttpServletResponse response) throws Exception{
        response.setCharacterEncoding(encode);
        Integer schunk=null;//当前分片数
        Integer schunks=null;//总分片数
        String name=null;
        String uploadPath="src\\main\\java\\com\\campus_assistant\\uploadFile";
        BufferedOutputStream os=null;
        try{
            DiskFileItemFactory factory=new DiskFileItemFactory();
            factory.setSizeThreshold(1024);//设置缓冲区
            factory.setRepository(new File(uploadPath));//上传文件的存储位置
            ServletFileUpload upload=new ServletFileUpload(factory);
            upload.setFileSizeMax(5l*1024l*1024l*1024l);//单个文件的大小限制
            upload.setSizeMax(10l*1024l*1024l*1024l);//总文件大小限制
            System.out.println(request);
            List<FileItem> items=upload.parseRequest(request);

            for (FileItem item : items) {
                if(item.isFormField()){
                    if("chunk".equals(item.getFieldName())){
                        schunk=Integer.parseInt(item.getString(encode));
                        System.out.println("当前分片数为："+schunk);
                    }
                    if("chunks".equals(item.getFieldName())){
                        schunks=Integer.parseInt(item.getString(encode));
                    }
                    if("name".equals(item.getFieldName())){
                        name=UUID.randomUUID()+item.getString(encode);
                        System.out.println(name);
                    }
                }
            }
            for (FileItem item : items) {
                if(!item.isFormField()){
                    String tempFileName=name;//分片文件名字
                    if(name!=null){
                        if(schunk!=null){
                            tempFileName=schunk +"_"+name;
                        }
                        File tempFile = new File(uploadPath, tempFileName);
                        if(!tempFile.exists()){
                            item.write(tempFile);//写入分片文件
                        }
                    }
                }
            }
            if(schunk!=null&&schunk.intValue()==schunks.intValue()-1){//读到最后一个分片时开始合并
                File tempFile=new File(uploadPath,name);
                os=new BufferedOutputStream(new FileOutputStream(tempFile));
                for (int i=0;i<schunks;i++){
                    System.out.println(i);
                    System.out.println("----------------------------------------------");
                    File file=new File(uploadPath,i+"_"+name);
                    while (!file.exists()){
                        System.out.println(i);
                        Thread.sleep(100);
                    }
                    System.out.println(i);
                    byte[] bytes = FileUtils.readFileToByteArray(file);//转化分片
                    os.write(bytes);
                    os.flush();
                    file.delete();//删除临时分片
                }
                os.flush();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(os!=null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager();
        poolingHttpClientConnectionManager.setMaxTotal(2000);
        poolingHttpClientConnectionManager.setDefaultMaxPerRoute(2000);
        HttpClients.custom().setConnectionManager(poolingHttpClientConnectionManager).setConnectionManagerShared(true).build();


        DynamicDataSource.dbName.set("db1");
        //获取到上传的文件
        String filePath=uploadPath + "\\" + name;
        File file=new File(filePath);
        System.out.println(file);
        InputStream inputStream=new FileInputStream(file);
        Workbook workbook= WorkbookFactory.create(inputStream);
        Sheet sheet=workbook.getSheetAt(0);
        Scores scores=new Scores();
        Cell cell=null;

        String studentName=null;
        String studentNum= null;
        String courseName=null;
        String score=null;
        String teacherName=null;

        String[] errorInformation=new String[5000];//存储错误信息
        int index=0;//错误信息下标

        List<Integer> allSid = scoresService.getAllSid();//获取已有的sid
        // 使用Set去除重复元素
        Set<Integer> setSid = new HashSet<>(allSid);
        System.out.println("setId:"+setSid);

        boolean result=false;//判断是否存入相同结果
        for (int i = 0; i <= sheet.getLastRowNum(); i++) {
            Row studentRow = sheet.getRow(i);
            if (i == 0) {//如果第一行是表头，则跳过
                if (studentRow.getCell(0).getStringCellValue().equals("学生姓名")){
                    continue;
                }

            }
            cell=studentRow.getCell(0);
            studentName = cell.getStringCellValue();//获得学生信息
            System.out.println(studentName);

            cell=studentRow.getCell(1);
            studentNum = String.valueOf((int)cell.getNumericCellValue());//获得学生学号
            System.out.println(studentNum);

            cell=studentRow.getCell(2);
            courseName = cell.getStringCellValue();//获得课程名称
            System.out.println(courseName);

            cell=studentRow.getCell(3);
            score = String.valueOf((int)cell.getNumericCellValue());//获得学生成绩
            System.out.println(score);

            cell=studentRow.getCell(4);
            teacherName=studentRow.getCell(4).getStringCellValue();//获得教师姓名
            System.out.println(teacherName);



            //获得cid与sid
            int sid = studentService.getIdByName(studentName);
            int cid=coursesService.getIdByCourseNameAndTeacherName(courseName,teacherName);
            if (sid==0){
                errorInformation[i++]="第"+i+"行未查询到该学生，请检查学生姓名是否输入正确";
            }else{
                if (cid==0){
                    errorInformation[i++]="第"+i+"行未查询到该课程，请检查任课老师姓名或课程名称是否输入正确";
                }else {
                    //判断是否已经存在该成绩
                    for (int sid2 : setSid) {
                        if(sid2==sid){
                            List<Integer> cidBySid = scoresService.getCidBySid(sid);
                            // 使用Set去除重复元素
                            Set<Integer> setCid = new HashSet<>(cidBySid);
                            System.out.println("该学生的sid为："+sid);
                            System.out.println("该学生的所有已经有成绩的课程id为："+setCid);
                            for (int cid2 : cidBySid) {
                                if(cid2==cid){
                                    System.out.println("第"+i+"行重复");
                                    errorInformation[i++]="第"+i+"行学生的该课程成绩已经存在";
                                    result=true;//说明已经重复
                                }
                            }
                        }

                        if(result==true){
                            break;
                        }
                    }

                    if(result==false){
                        scores.setSId(sid);
                        scores.setCId(cid);
                        scores.setExamResults(score);
                        System.out.println("填入的成绩为："+scores);
                        scoresService.addScores(scores);
                    }

                }
            }
        }
        return ToVue.suc(errorInformation);
    }


}
